<script setup lang="ts">
import dayjs from "dayjs";
import { ref, shallowRef, computed } from "vue";
import Taro, { useRouter } from "@tarojs/taro";

import ByIcon from "@/components/ui/ByIcon.vue";
import Page from "@/components/common/Page.vue";
import ByButton from "@/components/ui/ByButton.vue";
import ByInputNumber from "@/components/ui/ByInputNumber.vue";

import ApiOrder from "@/api/order";
import ApiPayment from "@/api/payment";
import ApiActivity from "@/api/activity";
import useFetch from "@/hooks/useFetch";
import useCountdown from "@/hooks/useCountdown";

import {
  calculateTimeDifference,
  formatSeconds,
  richTextFormater,
} from "@/utils";

import { TActivity, TActivityTicket, TActivityTicketSku } from "@/global";

// import { richTextFormater } from '@/utils';
// import useSubscribeMessage from '@/hooks/useSubscribeMessage';

const { params } = useRouter<{
  act_id: string;
}>();

type ChooseEtime = TActivityTicket["etime_list"][number] & {
  expired?: boolean;
};

const chooseEtime = ref<ChooseEtime>();
const chooseSku = ref<TActivityTicketSku>();

const quantity = ref(1);

// 查询活动票券规格
const { data: ticketData, run: runTicket } = useFetch<TActivityTicket>(
  ApiActivity.activityTicket,
  {
    immediate: false,
    afterFetch: (res: any) => res.detail,
  }
);

const renderEtimes = computed(() => {
  const list = (ticketData.value?.etime_list || []).map((e) => ({
    ...e,
    expired: checkedIsExpired(e),
  }));

  // 优先找到 第一个非过期场次
  const target = list.find((e) => !e.expired) || list[0];
  chooseEtime.value = target;

  return list;
});

// 计算选中场次权益包
const packageList = computed<(TActivityTicketSku & { isSellOut: boolean })[]>(
  () => {
    const id = chooseEtime.value?.id;

    const list = ticketData.value?.sku_list
      .filter(({ etime_id }) => etime_id == id)
      .map((e) => ({ ...e, isSellOut: e.sold_num >= e.stock_num }));

    // 设置默认选中项
    if (list?.length > 0) {
      choosePackageEvent(list[0]);
    }

    return list;
  }
);

// 早鸟票剩余时间，等于<=0 都表示不在时间范围内
const earlySeconds = shallowRef(0);
const { start } = useCountdown(earlySeconds);

// 查询活动详情
const { data: activityData } = useFetch<TActivity>(
  ApiActivity.activityDetailConsumer,
  {
    defaultParams: { id: +params.act_id },
    afterFetch: (res: any) => res.detail,
    onSuccess(res) {
      if (res.early_start_time) {
        earlySeconds.value = calculateTimeDifference(
          res.early_end_time,
          res.early_start_time
        );
        start();
      }

      // 获取活动售票规格
      runTicket({ ticket_id: res.ticket_id });
    },
  }
);

// 获取当前显示价格,如果当前是早鸟价期间，优先显示早鸟价格
const getSkuPrice = (): number => {
  const { early_price = 0, sku_price = 0 } = chooseSku.value || {};
  return (earlySeconds.value > 0 ? early_price : sku_price) || sku_price;
};

// 选择场次
const changeEtimeEvent = function (etime) {
  if (!etime.expired) {
    quantity.value = 1;
    chooseSku.value = undefined;
    chooseEtime.value = etime;
  }
};

// 选择权益包
const choosePackageEvent = function (e) {
  if (chooseEtime.value?.expired || e.isSellOut) return;

  const skuId = e.id;

  chooseSku.value = ticketData.value.sku_list.find((item) => item.id == skuId);
  quantity.value = 1;
};

// 支付加载状态
const payLoading = ref(false);
/**
 *  支付收款流程
 *  1. 创建订单
 *  2. 获取JSAPI支付参数
 *  3. 发起支付
 *  4. 反馈结果
 */
const createOrderAndPay = async () => {
  try {
    const { act_id, ticket_id, etime_id, id, sku_name, sku_title } =
      chooseSku.value!;

    const { confirm } = await Taro.showModal({
      title: "购买提示",
      content: `您正在购买${quantity.value}份“${sku_name}”`,
      confirmText: "确认",
    });

    if (!confirm) return;

    payLoading.value = true;

    const {
      data: { value },
    } = await useFetch<{ sn: string }>(ApiOrder.createTicketOrder, {
      defaultParams: {
        act_id,
        etime_id,
        ticket_id,
        sku_id: id,
        sku_title,
        quantity: quantity.value,
        sku_price: getSkuPrice(),
      },
    });

    const {
      data: { value: payParams },
    } = await useFetch<any>(ApiPayment.payment, {
      defaultParams: {
        order_sn: value.sn,
        pay_type: "wechat_pay",
        // 订单类型 1 押金订单 2 收款订单 3 售票订单
        service_type: 3,
      },
    });

    Taro.requestPayment({
      timeStamp: payParams.time_stamp,
      nonceStr: payParams.nonce_str,
      package: payParams.package,
      signType: payParams.sign_type,
      paySign: payParams.pay_sign,
    }).then(
      (res) => {
        // @ts-expect-error
        if (res.payCompletedPage) {
          // @ts-expect-error
          res.payCompletedPage.onLoad(() => {
            console.log("支付订单详情页加载完成");
            console.log("处于支付订单详情页的时候【不允许】调用 wx.navigateTo");
          });

          // @ts-expect-error
          res.payCompletedPage.onUnload(() => {
            console.log("支付订单详情页卸载完成");
            console.log("退出支付订单详情页之后，允许调用 wx.navigateTo");

            // 重定向到首页
            Taro.redirectTo({
              url: `ticketResult?sn=${payParams.sn}&actId=${params.act_id}&name=${chooseSku.value?.sku_name}`,
            });
          });
        } else {
          Taro.redirectTo({
            url: `ticketResult?sn=${payParams.sn}&actId=${params.act_id}&name=${chooseSku.value?.sku_name}`,
          });
        }
      },
      (err) => {
        console.error("支付失败", err);
        Taro.showToast({ icon: "error", title: "支付失败" });
      }
    );
  } catch (err) {
    console.error("购买失败", err);
  } finally {
    payLoading.value = false;
  }
};

const checkedIsExpired = (item: any) => {
  if (item.etime_type === 1) {
    const currentTime = dayjs();
    const target = dayjs(`${item.etime_day} ${item.end_time}`);

    return currentTime.isAfter(target);
  }
};
</script>

<template>
  <Page hiddenHeaderBg footerSticky>
    <template
      #footer
      v-if="activityData?.is_ticket && activityData?.is_ticket == 1"
    >
      <view class="bg-light">
        <view class="flex items-center py-3 px-3" :class="['justify-between']">
          <view class="text-dark">
            <text class="text-2xl">
              合计: ¥{{ (getSkuPrice() * quantity).toFixed(2) }}
            </text>
          </view>

          <ByButton
            class="w-1/2 bg-dark"
            :loading="payLoading"
            :disabled="!chooseSku || quantity === 0 || chooseEtime?.expired"
            @tap="createOrderAndPay"
          >
            立即购买
          </ByButton>
        </view>
        <view class="safe-footer" />
      </view>
    </template>

    <view class="mx-3 my-3">
      <view class="flex p-3 bg-primary rounded-lg mt-3">
        <!-- S 封面图 -->
        <view>
          <image
            :src="activityData?.title_small_img || activityData?.title_img"
            class="w-[250px] h-[200px] mr-3 rounded-lg"
          />
        </view>
        <!-- E 封面图 -->

        <!-- S 基本信息 -->
        <view class="flex flex-col text-light">
          <view class="flex-auto mb-2 text-2xl">
            {{ activityData?.title }}
          </view>

          <view class="flex-none">
            <view class="flex items-center mt-2">
              <view class="text-xs whirespace-pre">
                {{ activityData?.act_time }}
              </view>
            </view>

            <view class="flex-auto text-xs line-clamp">
              {{ activityData?.street || activityData?.address }}
            </view>
          </view>
        </view>
        <!-- E 基本信息 -->
      </view>

      <!-- S 场次信息 -->
      <view class="text-dark my-6">
        <view class="mb-2 text-lg">场次</view>

        <view class="flex flex-wrap">
          <view
            v-for="(item, index) in renderEtimes"
            :key="item.id"
            class="relative flex-none w-1/2"
          >
            <view
              :lineClamp="1"
              :class="[
                'border rounded-full px-2 py-2 mt-2 text-center',
                {
                  'bg-error text-white border-error':
                    item.id == chooseEtime?.id,
                  'opacity-20': item.expired,
                  'mr-2': index % 2 === 0,
                },
              ]"
              @tap="changeEtimeEvent(item)"
            >
              {{ item.etime_title }}
            </view>

            <view
              v-if="item.expired"
              class="absolute top-0 right-2 px-1 rounded-full bg-[#ffeace] text-error"
            >
              售罄
            </view>
          </view>
        </view>
      </view>
      <!-- E 场次信息 -->

      <!-- S 权益包信息 -->
      <view class="text-dark my-6 py-6 border-b-1 border-t-1">
        <view class="flex items-center justify-between">
          <view class="mb-2 text-lg">权益包</view>

          <view
            v-if="earlySeconds > 0"
            class="flex-center py-1 px-2 rounded-full bg-dark text-white text-sm"
          >
            <ByIcon name="Bird" :size="40" />
            <text class="pl-1">
              早鸟特惠，
              <text v-if="earlySeconds <= 86400">
                剩余时间：{{ formatSeconds(earlySeconds) }}
              </text>
              <text v-else>
                截止：{{ activityData?.early_end_time.split(" ")[0] }}
              </text>
            </text>
          </view>
        </view>

        <view class="">
          <view v-for="item in packageList" :key="item.id" class="relative">
            <view
              :class="[
                'flex items-center border-primary border rounded-lg p-3 mt-3',
                {
                  'bg-primary text-dark': item.id == chooseSku?.id,
                  'opacity-40': chooseEtime?.expired,
                },
              ]"
              @tap="choosePackageEvent(item)"
            >
              <view class="flex-none w-3/5">
                <view class="text-lg">{{ item.sku_name }}</view>

                <view class="mt-2 flex items-end">
                  <template v-if="earlySeconds > 0 && item.early_price > 0">
                    <text class="text-lg">¥{{ item.early_price }}</text>
                    <text class="line-through ml-2"
                      >¥{{ item.sku_price }}
                    </text>
                  </template>

                  <text v-else class="text-lg">¥{{ item.sku_price }}</text>
                </view>
              </view>

              <view
                class="text-center"
                v-if="
                  !(chooseEtime?.expired || item.isSellOut) &&
                  item.id == chooseSku?.id
                "
              >
                <ByInputNumber
                  v-model="quantity"
                  :disabled="chooseEtime?.expired"
                  :max="item.sale_limit || undefined"
                />
                <view class="text-xs mt-2" v-if="item.sale_limit > 0">
                  最大购买数量：{{ item.sale_limit }}
                </view>
              </view>
            </view>

            <view
              v-if="chooseEtime?.expired || item.isSellOut"
              class="absolute top-1/2 right-7 text-error -translate-y-1/2 text-lg"
              >售罄</view
            >
          </view>
        </view>
      </view>
      <!-- E 权益包信息 -->

      <!-- S 购买须知 -->
      <view class="text-dark my-6">
        <view class="mb-2 text-lg">购买须知</view>
        <view class="">
          <rich-text :nodes="richTextFormater(activityData?.purchase_notice)" />
        </view>
      </view>
      <!-- E 购买须知 -->
    </view>
  </Page>
</template>
